﻿open System
open System.IO
open Microsoft.FSharp.Text.Lexing

open TinyJava.Ast
open Lexer
open Parser
open Environment
open TypeRules
open ExceptionMonad
open TinyJava.TAC

let Compile() =
  try
    let inputChannel = new StreamReader("Program.tj")
    printfn "%s" "Parsing..."
    let lexbuf = LexBuffer<char>.FromTextReader inputChannel
    let ast = Parser.start Lexer.tokenize lexbuf //parse the file and create the AST
    printfn "%s" "Done!"
    printfn "%s" "Type checking/Building symbol table..."
    let partial_table = fill_table ast //initialize the symbol table with class,field and method infos
    let empty_block_table = {Vars = [];Parent = None;Owner = None;Child = None}
    let environment = {SymbolTable = partial_table;BlockTable = ref(empty_block_table);CurrentClass = "";CheckReturn = false;ReturnFound = false;LoopCounter = 0}
    let type_check_result = execute eval_program ast environment
    match type_check_result with
    | Statement(_,typed_env) -> ()
    | Exception(error) -> failwith error
    printfn "%s" "Generating TAC code..."
    let tac_code = generate_tac ast
    do tac_log tac_code false
    printfn "%s" "Done!"
    1
  with
    | Failure(msg) -> 
        printfn "%s" msg
        printfn "%s" "Build aborted..."
        0

Compile() |> ignore